/*
 * Copyright (c) 2009 Sun Microsystems, Inc.
 * Copyright (c) 2011 Oracle Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **/

package com.sun.spot.wot.gateway;

import com.sun.spot.ipv6.io.j2me.udp.UDPConnection;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;

/**
 *
 * @author vgupta
 */
public class UDP6Advertiser extends Thread {
    private UDPConnection rCon = null;
    private Datagram dg = null;
    private boolean done = false;
    byte[] advertisementBytes;
    private int period;
    private long lastSent = 0;
    private boolean initOk = false;
    private Date d = new Date();
    
    public UDP6Advertiser(byte[] advertisementBytes, int period) throws Exception {
        if (advertisementBytes != null) {
            this.advertisementBytes = new byte[advertisementBytes.length];
            System.arraycopy(advertisementBytes, 0, this.advertisementBytes, 0,
                    advertisementBytes.length);
        }
        this.period = period;
        try {
            rCon = (UDPConnection) Connector.open("udp://" + "broadcast" + ":" +
                    //"[fe80:0:0:0:0214:4f01:0000:5317]:" +
                    Constants.UDP6_ADVPORT);
            dg = rCon.newDatagram(rCon.getMaximumLength());
            //dg.reset(); /// why do I need this??
            dg.write(advertisementBytes, 0, advertisementBytes.length);
            initOk = true;
        } catch (Exception e) {
            System.err.println("Caught " + e + " in connection initialization.");
            e.printStackTrace();
            System.exit(1);
        }

        if (!initOk) {
            System.out.println("UDPAdvertiser initialization failed");
        } else {
            System.out.println("UDPAdvertiser started (will broadcast on port " +
                    Constants.UDP6_ADVPORT + ")");
        }
    }

    public void markDone() {
        done = true;
    }

    public void sendUnsolicitedAdv() {
        try {
            rCon.send(dg);
            lastSent = System.currentTimeMillis();
            d.setTime(lastSent);
            System.out.println(d.toString() + ": Sent unsolicited UDP advertisement on port " +
                    Constants.UDP6_ADVPORT);
        } catch (IOException ex) {
            System.err.println("Caught " + ex);
            ex.printStackTrace();
            Logger.getLogger(UDP6Advertiser.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }

    public void run() {
        try {
            try {
                while (!done) {
                    try {
                        if (System.currentTimeMillis() > (lastSent + period)) {
                            sendUnsolicitedAdv();
                        }
                        Thread.sleep(2000);
                    } catch (Exception ex) {
                        Logger.getLogger(UDP6Advertiser.class.getName()).
                                log(Level.SEVERE, null, ex);
                    }
                }
                System.out.println("Shutting down UDP Advertiser");

            } finally {
                rCon.close();
            }
        } catch (IOException ex) {
            System.err.println("Caught " + ex + " in UDP6Advertiser run");
            ex.printStackTrace();
        }
    }
}
